Replace jquery.serializeObject with new implementation

The old serializeObject function serialized checked checkboxes as an array which was not correct and with
strong_parameters enabled it triggered a `UnpermittedParameters` error.

In the AgentEditPage javascript we only need to initialize `select2` when then `#agent_type` field is a select
box (trying to call `select2` on normal text fields caused a javascript error in the feature specs)

Dominik Sander 7 years ago
parent
commit
517e42c9d2

+ 1 - 1
app/assets/javascripts/pages/agent-edit-page.js.coffee

@@ -36,7 +36,7 @@ class @AgentEditPage
36 36
       @handleTypeChange(true)
37 37
 
38 38
       # Update the dropdown to match agent description as well as agent name
39
-      $('#agent_type').select2
39
+      $('select#agent_type').select2
40 40
         width: 'resolve'
41 41
         formatResult: formatAgentForSelect
42 42
         escapeMarkup: (m) ->

+ 10 - 0
spec/features/form_configurable_feature_spec.rb

@@ -0,0 +1,10 @@
1
+require 'capybara_helper'
2
+
3
+describe "form configuring agents", js: true do
4
+  it 'completes fields with predefined array values' do
5
+    login_as(users(:bob))
6
+    visit edit_agent_path(agents(:bob_csv_agent))
7
+    check('Propagate immediately')
8
+    select2("serialize", from: "Mode")
9
+  end
10
+end

+ 6 - 0
spec/fixtures/agents.yml

@@ -139,6 +139,12 @@ bob_basecamp_agent:
139 139
   service: generic
140 140
   guid: <%= SecureRandom.hex %>
141 141
 
142
+bob_csv_agent:
143
+  type: Agents::CsvAgent
144
+  user: bob
145
+  name: "Bob's CsvAgent"
146
+  guid: <%= SecureRandom.hex %>
147
+
142 148
 jane_basecamp_agent:
143 149
   type: Agents::BasecampAgent
144 150
   user: jane

+ 142 - 36
vendor/assets/javascripts/jquery.serializeObject.js

@@ -1,40 +1,146 @@
1
-//
2
-// Use internal $.serializeArray to get list of form elements which is
3
-// consistent with $.serialize
4
-//
5
-// From version 2.0.0, $.serializeObject will stop converting [name] values
6
-// to camelCase format. This is *consistent* with other serialize methods:
7
-//
8
-//   - $.serialize
9
-//   - $.serializeArray
10
-//
11
-// If you require camel casing, you can either download version 1.0.4 or map
12
-// them yourself.
13
-//
14
-
15
-(function($){
16
-  $.fn.serializeObject = function () {
17
-    "use strict";
18
-
19
-    var result = {};
20
-    var extend = function (i, element) {
21
-      var node = result[element.name];
22
-
23
-  // If node with same name exists already, need to convert it to an array as it
24
-  // is a multi-value field (i.e., checkboxes)
25
-
26
-      if ('undefined' !== typeof node && node !== null) {
27
-        if ($.isArray(node)) {
28
-          node.push(element.value);
29
-        } else {
30
-          result[element.name] = [node, element.value];
1
+/**
2
+ * jQuery serializeObject
3
+ * @copyright 2014, macek <paulmacek@gmail.com>
4
+ * @link https://github.com/macek/jquery-serialize-object
5
+ * @license BSD
6
+ * @version 2.5.0
7
+ */
8
+(function(root, factory) {
9
+
10
+  // AMD
11
+  if (typeof define === "function" && define.amd) {
12
+    define(["exports", "jquery"], function(exports, $) {
13
+      return factory(exports, $);
14
+    });
15
+  }
16
+
17
+  // CommonJS
18
+  else if (typeof exports !== "undefined") {
19
+    var $ = require("jquery");
20
+    factory(exports, $);
21
+  }
22
+
23
+  // Browser
24
+  else {
25
+    factory(root, (root.jQuery || root.Zepto || root.ender || root.$));
26
+  }
27
+
28
+}(this, function(exports, $) {
29
+
30
+  var patterns = {
31
+    validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
32
+    key:      /[a-z0-9_]+|(?=\[\])/gi,
33
+    push:     /^$/,
34
+    fixed:    /^\d+$/,
35
+    named:    /^[a-z0-9_]+$/i
36
+  };
37
+
38
+  function FormSerializer(helper, $form) {
39
+
40
+    // private variables
41
+    var data     = {},
42
+        pushes   = {};
43
+
44
+    // private API
45
+    function build(base, key, value) {
46
+      base[key] = value;
47
+      return base;
48
+    }
49
+
50
+    function makeObject(root, value) {
51
+
52
+      var keys = root.match(patterns.key), k;
53
+
54
+      // nest, nest, ..., nest
55
+      while ((k = keys.pop()) !== undefined) {
56
+        // foo[]
57
+        if (patterns.push.test(k)) {
58
+          var idx = incrementPush(root.replace(/\[\]$/, ''));
59
+          value = build([], idx, value);
60
+        }
61
+
62
+        // foo[n]
63
+        else if (patterns.fixed.test(k)) {
64
+          value = build([], k, value);
65
+        }
66
+
67
+        // foo; foo[bar]
68
+        else if (patterns.named.test(k)) {
69
+          value = build({}, k, value);
31 70
         }
32
-      } else {
33
-        result[element.name] = element.value;
34 71
       }
35
-    };
36 72
 
37
-    $.each(this.serializeArray(), extend);
38
-    return result;
73
+      return value;
74
+    }
75
+
76
+    function incrementPush(key) {
77
+      if (pushes[key] === undefined) {
78
+        pushes[key] = 0;
79
+      }
80
+      return pushes[key]++;
81
+    }
82
+
83
+    function encode(pair) {
84
+      switch ($('[name="' + pair.name + '"]', $form).attr("type")) {
85
+        case "checkbox":
86
+          return pair.value === "on" ? true : pair.value;
87
+        default:
88
+          return pair.value;
89
+      }
90
+    }
91
+
92
+    function addPair(pair) {
93
+      if (!patterns.validate.test(pair.name)) return this;
94
+      var obj = makeObject(pair.name, encode(pair));
95
+      data = helper.extend(true, data, obj);
96
+      return this;
97
+    }
98
+
99
+    function addPairs(pairs) {
100
+      if (!helper.isArray(pairs)) {
101
+        throw new Error("formSerializer.addPairs expects an Array");
102
+      }
103
+      for (var i=0, len=pairs.length; i<len; i++) {
104
+        this.addPair(pairs[i]);
105
+      }
106
+      return this;
107
+    }
108
+
109
+    function serialize() {
110
+      return data;
111
+    }
112
+
113
+    function serializeJSON() {
114
+      return JSON.stringify(serialize());
115
+    }
116
+
117
+    // public API
118
+    this.addPair = addPair;
119
+    this.addPairs = addPairs;
120
+    this.serialize = serialize;
121
+    this.serializeJSON = serializeJSON;
122
+  }
123
+
124
+  FormSerializer.patterns = patterns;
125
+
126
+  FormSerializer.serializeObject = function serializeObject() {
127
+    return new FormSerializer($, this).
128
+      addPairs(this.serializeArray()).
129
+      serialize();
130
+  };
131
+
132
+  FormSerializer.serializeJSON = function serializeJSON() {
133
+    return new FormSerializer($, this).
134
+      addPairs(this.serializeArray()).
135
+      serializeJSON();
39 136
   };
40
-})(jQuery);
137
+
138
+  if (typeof $.fn !== "undefined") {
139
+    $.fn.serializeObject = FormSerializer.serializeObject;
140
+    $.fn.serializeJSON   = FormSerializer.serializeJSON;
141
+  }
142
+
143
+  exports.FormSerializer = FormSerializer;
144
+
145
+  return FormSerializer;
146
+}));